package com.uyaer.engine.loader
{
	import com.uyaer.engine.utils.HashMap;
	import com.uyaer.engine.utils.Utils;
	
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;

	public class LoaderManager
	{
		private static var myinstance:LoaderManager = new LoaderManager();
		private var resArr:Vector.<MyLoaderInfo> = new Vector.<MyLoaderInfo>();
		private var currLoaderInfo:MyLoaderInfo;
		private var loader:Loader;
		private var urlLoaderMap:HashMap = new HashMap();
		private var urlLoaderInfoMap:HashMap = new HashMap();
		private var context:LoaderContext;
		
		private var isLoading:Boolean = false; //是否在进行加载
		public function LoaderManager()
		{
			context = new LoaderContext();
			context.applicationDomain = ApplicationDomain.currentDomain;
			
			loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE , _onLoadOverHandler);
			loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, _onProgressHandler);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, _onErrorHandler);
		}
		
		private function _onErrorHandler(e:IOErrorEvent):void{
			currLoaderInfo && currLoaderInfo.errorFun && currLoaderInfo.errorFun();
		}
		
		private function _onProgressHandler(e:ProgressEvent):void{
			currLoaderInfo && currLoaderInfo.progressFun && currLoaderInfo.progressFun();
		}
		
		private function _onLoadOverHandler(e:Event):void{
			currLoaderInfo && currLoaderInfo.successFun && currLoaderInfo.successFun(loader.content);
			loader.unload();
			this.load();
		}
		
		public function loadBinary(res:MyLoaderInfo, data:* = null, type:String = URLLoaderDataFormat.TEXT):void{
			var oneLoader:MyURLLoader = new MyURLLoader(new URLRequest(res.url));
			oneLoader.dataFormat = type;
			oneLoader.odata = data; 
			oneLoader.mark = Utils.rangString(4) + Utils.now();
			oneLoader.addEventListener(Event.COMPLETE,_onURLLoaderOverHandler);
			oneLoader.addEventListener(ProgressEvent.PROGRESS,_onURLLoaderProgressHandler);
			oneLoader.addEventListener(IOErrorEvent.IO_ERROR,_onURLLoaderErrorHandler);
			urlLoaderMap.put(oneLoader.mark , oneLoader);
			urlLoaderInfoMap.put(oneLoader.mark, res);
		}
		
		private function _onURLLoaderErrorHandler(e:IOErrorEvent):void{
			var urlLoder:MyURLLoader = e.target as MyURLLoader;
			var info:MyLoaderInfo = urlLoaderInfoMap.get(urlLoder.mark) as MyLoaderInfo;
			info && info.errorFun && info.errorFun(); 
		}
		
		private function _onURLLoaderProgressHandler(e:ProgressEvent):void{
			var urlLoder:MyURLLoader = e.target as MyURLLoader;
			var info:MyLoaderInfo = urlLoaderInfoMap.get(urlLoder.mark) as MyLoaderInfo;
			info && info.progressFun && info.progressFun();
		}
		
		private function _onURLLoaderOverHandler(e:Event):void{
			var urlLoder:MyURLLoader = e.target as MyURLLoader;
			var info:MyLoaderInfo = urlLoaderInfoMap.get(urlLoder.mark) as MyLoaderInfo;
			info && info.successFun && info.successFun(urlLoder.data,urlLoder.odata);
			urlLoder.removeEventListener(Event.COMPLETE, _onURLLoaderOverHandler);
			urlLoder.removeEventListener(ProgressEvent.PROGRESS, _onURLLoaderProgressHandler);
			urlLoder.removeEventListener(IOErrorEvent.IO_ERROR, _onURLLoaderErrorHandler);
			urlLoder.close();
			urlLoaderInfoMap.remove(urlLoder.mark);
			urlLoaderMap.remove(urlLoder.mark);
		}
		
		/**
		 *开始加载资源 
		 * 
		 */		
		private function load():void{
			if(resArr.length){
				currLoaderInfo = resArr.shift();
				loader.load(new URLRequest(currLoaderInfo.url),context);
				isLoading = true;
			}else{
				isLoading = false;
			}
		}
		
		public static function get instance():LoaderManager{
			return myinstance;
		}
		
		/**
		 *添加资源进行 
		 * @param res
		 * 
		 */		
		public function add(res:MyLoaderInfo):void{
			resArr.push(res);
			resArr.sort(compareWeight);
			if(!isLoading){
				this.load();
			}
		}
		
		/**
		 *添加一组资源 
		 * @param res
		 * 
		 */		
		public function adds(res:Vector.<MyLoaderInfo>):void{
			resArr.concat(res);
			resArr.sort(compareWeight);
			if(!isLoading){
				this.load();
			}
		}
		
		private function compareWeight(info1:MyLoaderInfo , info2:MyLoaderInfo):int{
			if(info1.weight > info2.weight){
				return 1;
			}else if(info1.weight < info2.weight){
				return  -1;
			}else{
				if(info1.timestamp > info2.timestamp){
					return 1;
				}else{
					return -1;
				}
			}
			return 0;
		}
	}
}